package com.kx.talk.service.impl;

import com.kx.base.vo.UserVO;
import com.kx.talk.cache.UserCache;
import com.kx.talk.mapper.FriendRelationMapper;
import com.kx.talk.mapper.MessageDao;
import com.kx.talk.mapper.MessageMapper;
import com.kx.talk.pojo.FriendRelation;
import com.kx.talk.pojo.FriendRelationExample;
import com.kx.talk.pojo.Message;
import com.kx.talk.service.TalkService;
import com.kx.talk.vo.UnReadCountVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 这个是聊天接口的拆表的实现
 * 水平拆表
 *
 * @author Sun
 * @date 2021/8/2 21:52
 */
@Service
public class TalkServiceTablesImpl implements TalkService {
    public static final int TABLE_COUNT = 2;
    @Resource
    private FriendRelationMapper friendRelationDao;

    @Resource
    private MessageMapper messageMapper;

    @Resource
    private MessageDao messageDao;

    @Resource
    private UserCache userCache;

    @Override
    public int sendMessage(Long sendUserId, Long receiveUserId, String message, Long messageTypeId) {
        //判断sendUserId的时候，receiveUserId是否把sendUserId移除了。
        FriendRelationExample example = new FriendRelationExample();
        FriendRelationExample.Criteria criteria = example.createCriteria();
        //sendUserId代表张三
        //receiveUserId代表李四
        //张三给李四发消息，应该看看李四是否删除了张三。
        criteria.andUserIdEqualTo(receiveUserId);
        criteria.andFriendIdEqualTo(sendUserId);

        List<FriendRelation> friendRelations = friendRelationDao.selectByExample(example);
        if (friendRelations == null || friendRelations.size() == 0) {
            //对方和您不是朋友关系。
            return -1;
        }
        //把消息放入数据库中
        Message msg = new Message();
        msg.setMessage(message);
        msg.setMessageTypeId(messageTypeId);
        msg.setSendTime(new Date(System.currentTimeMillis()));
        msg.setSendUserId(sendUserId);
        msg.setReceiveUserId(receiveUserId);
        msg.setReadState(0);
        msg.setIsDelete(0);
        return messageDao.insertMessage(msg, sendUserId % 2, receiveUserId % 2);
    }

    @Override
    public Integer modifyMessageReadState(Long sendUserId, Long receiveUserId, Long messageId, Integer readState) {
        //根据发送人id和接收人id确定在哪个表中,然后根据消息id确定唯一消息
        return messageDao.updateMessageReadState(sendUserId % 2, receiveUserId % 2, messageId, readState);
    }

    @Override
    public List<Message> selectPageChartRecord(Long selfUserId, Long otherUserId, Long selfSendLastItemId, Long otherSendLastItemId, Integer pageSize) {
        int table1_index1 = (int) ((selfUserId) % TABLE_COUNT);
        //Long%int
        //结果是？  Long？ long！
        int table1_index2 = (int) ((otherUserId) % TABLE_COUNT);
        int table2_index1 = (int) ((otherUserId) % TABLE_COUNT);
        int table2_index2 = (int) ((selfUserId) % TABLE_COUNT);
        //分为四种情况
        if (selfSendLastItemId == null && otherSendLastItemId == null) {
            return messageDao.selectFirstPageChartRecord(selfUserId, otherUserId, pageSize, table1_index1, table1_index2, table2_index1, table2_index2);
        } else if (selfSendLastItemId != null && otherSendLastItemId == null) {
            return messageDao.selectOtherFirstPageChartRecord(selfUserId, otherUserId, pageSize, otherSendLastItemId, table1_index1, table1_index2, table2_index1, table2_index2);
        } else if (selfSendLastItemId == null && otherSendLastItemId != null) {
            return messageDao.selectSelfFirstPageChartRecord(selfUserId, otherUserId, pageSize, selfSendLastItemId, table1_index1, table1_index2, table2_index1, table2_index2);
        } else {
            return messageDao.selectPageChartRecord(selfUserId, otherUserId, pageSize, selfSendLastItemId, otherSendLastItemId, table1_index1, table1_index2, table2_index1, table2_index2);
        }
    }

    @Override
    public long selectUnreadCountByUserId(Long userId) {
        //接收人是userId
        //我们需要查询的数据可以判断出是哪张表吗？
        List<Void> tableCounts = new ArrayList<>();
        for (int i = 0; i < TABLE_COUNT; i++) {
            tableCounts.add(null);
        }

        int index2 = (int) (userId % TABLE_COUNT);
        return messageDao.selectUnreadCountByUserId(userId, index2, tableCounts);
    }

    @Override
    public List<UnReadCountVO> selectUnReadCountGroupBy(Long userId) {
        List<Void> tableCounts = new ArrayList<>();
        for (int i = 0; i < TABLE_COUNT; i++) {
            tableCounts.add(null);
        }
        int index2 = (int) (userId % TABLE_COUNT);
        List<UnReadCountVO> unReadCountVOS = messageDao.selectUnreadCountGroupBy(userId, index2, tableCounts);
        List<Long> userIds = new ArrayList<>();
        for (UnReadCountVO unReadCountVO : unReadCountVOS) {
            userIds.add(unReadCountVO.getFriendId());
        }
        List<UserVO> users = userCache.getUsers(userIds);
        for (UserVO user : users) {
            for (UnReadCountVO unReadCountVO : unReadCountVOS) {
                if(user.getId().equals(unReadCountVO.getFriendId())){
                    unReadCountVO.setUser(user);
                }
            }
        }
        return unReadCountVOS;
    }
}
